[contents] [prev] [top] (5 out of 5)

Output

Every ScriptX object can be printed using a set of global functions that print a text-only representation of that object to an output stream. How an object's printable representation appears depends on how that class has defined it. In many cases, the printable representation may be nothing more than the name of the object's class and its memory address. In other cases, the class may define its printable representation to contain significant information about the value or contents of that object.

Printable representations are useful for debugging purposes. Be careful when using an object's printable representation to refer to that object-the object's printable representation may not be the same thing you would type into a script to create or query that object.

ScriptX defines a default stream named debug for printable representations. In some ScriptX environments, the debug stream may be attached to a listener or debugging window. You can also create additional streams and use them as the stream argument to each of the functions described in this section.

The Short Answer

The simplest way to get the printable representation of an object is to call the function print on it. The print global function writes a representation of the object to the debug stream. This form of printing is used extensively in examples throughout this book.

t := new Rect
print t
[0, 0, 0, 0] as Rect
r := new LinkedList
print r
#() as LinkedList

The function call print "t" appears to have the same output in the Listener window as the simply typing the string literal "t", followed by a newline character. The difference is that the print function actually prints to a stream, the debug stream, which can be directed to the Listener window, or to another window, such as a debugger. You can do simple formatted output by coercing the printable representation of any object into a string, adding it to another string as a label, and then printing the result:

print ("r contains: " + (r as String)) 
"r contains #() as LinkedList"

The prin Generic Function

The basic generic function for printing objects is prin. Many classes in the ScriptX core classes implement a prin method; prin is commonly specialized by scripted classes.

prin objectToPrint option stream
where:

The prin method prints objectToPrint to stream using the specified option without including a newline character at the end of the line.

See the "Streams" chapter of ScriptX Components Guide and the ScriptX Class Reference for more information about streams.

Unlike the print function, which is a global function that is not associated with any class, prin is a generic function. It is defined as a method by the root system class, RootObject, and can be specialized by any class in the system that requires a special printed representation. The prin generic function is used as a primitive by all other printing functions, most of which, like print, are global functions. By specializing prin for a class, you can assure that all ScriptX printing functions can print that class. (In certain classes that contain recursive structures, it is necessary to specialize the recurPrin generic function as well.)

By default, ScriptX provides only one appropriate stream for printable information-the debugging stream, referenced by the system global variable debug. Streams can also be instances of the class String or a stream that you have created yourself.

The option argument to prin may be one of the following names. Some classes, notably the Exception classes, define other options available to prin, but at least these four must be available:

In the following examples, the result (specified by ) is the output printed to the stream, not the result of the prin expression itself:

a := "test string"
prin a @normal debug
"test string"
prin a @debug debug
StringConstant: "test string"
prin a @unadorned debug
test string

t := #(1,2,3,4)
prin t @normal debug
#(1, 2, 3, 4)
prin t @unadorned debug
1234
prin t @debug debug
Array@0x3904e8: #(ImmediateInteger: 1, ImmediateInteger: 2,
ImmediateInteger: 3, ImmediateInteger: 4)

t := #(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
prin t @normal debug -- default is only 10 elements
#(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...)
prin t @complete debug -- @complete prints all the elements
#(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)

Other Printing Functions

The generic function prin is used by several global functions, summarized here, which can be used as shortcuts to the prin generic. Printing functions are described in detail in the "Global Functions" chapter of the ScriptX Class Reference.

prinln self arg [stream]
prinln operates in the same manner as prin, except it also prints a newline character after the output.

prin1 self [stream]
prin1 is equivalent to prin with the @normal option. The stream argument is optional and defaults to debug.

print object [stream]
A combination of prinln and prin1, the print function prints the object representation to stream with the @normal option and a newline character. The stream argument is optional and defaults to debug. See the discussion and examples that begin on page 73.

prinString object arg
prinString yields a new String instance containing a printed representation of the given object.

printString object 
printString is equivalent to prinString, except that it forces the @normal option.

shortPrin object arg stream length
shortPrin is equivalent to prin, except that shortPrin prints only the number of characters specified by length.

Formatted Output

Generalized formatted output is available with the format function:

format stream  formatString  object  option
The format global function prints a formatted string to a stream, where stream is the stream to print to, (for example, debug), formatString is the string to print (which can include substitution characters), object is the object you want a printable representation of, and option is one of the four printing options, as described on page 74. The final argument is optional-if it is not supplied, it is passed as undefined and defaults to @normal.

The stream and object arguments to format are in a different order than 
in prin and its associated functions.
The formatString argument is a string that may contain substitution characters. Those substitution characters represent the object being printed, and are replaced in the resulting output by the printable representation of that object. For single objects, use "%*" as a substitution character.

i := 15
format debug "I is %*\n" i @normal
I is 15

Note that the format string can contain special characters such as newlines.

To print out a number of objects in one format string, you can put those objects in an array and use the array element substitution character. For multiple objects, the substitution character is "%n" where n is the position of the element in the collection. The "%" can be used as a terminator after n. If you use this form for multiple elements in a collection, the option argument of the format expression must be a collection of options (such as an array), with a separate option for every element being printed.

format debug "%1 and %2% are dead\n" \
#("rosencrantz", "guildenstern") #(@unadorned,@unadorned)
rosencrantz and guildenstern are dead

As a shorthand for printing an array of options, the letters n, c, u, and d can be inserted after individual items. This allows items to be printed out with different formats. When individual formats are supplied, they override formats that are supplied in the fourth argument.

-- in this example, format codes %n1 and %u2 make the final
-- argument unnecessary
format debug "%n1 and %u2 are dead\n" #("rosencrantz", "guildenstern")
"rosencrantz" and guildenstern are dead
-- in this example, @unadorned overrides @debug for both items
format debug "%u1 and %u2 are dead\n" \
	 #("rosencrantz", "guildenstern") #(@debug,@debug)
rosencrantz and guildenstern are dead

If you use the "%*" substitution in a format string on a collection object, the resulting output string contains the entire printable representation of that object:

format debug "The array is: %*" w @normal
The array is: #("rosencrantz", "guildenstern")

The "%n" substitution only works on collections that implement the getNth method. See Chapter 7, "Collections," or the "Collections" chapter of the ScriptX Components Guide for more information about collections. If you use the "%n" substitution on objects that are not collections, ScriptX reports an exception.

Recursive Output

Objects that contain other objects, for example collections such as arrays or keyed lists, may contain multiple copies of the same object, and may even contain references to themselves. In such a case, the printable representation of that object has a special format to manage recursion:

keepOnGoing := #(1,2,3)
append keepOnGoing keepOnGoing

In this example, append added the array keepOnGoing to itself as its own fourth element. Without a special format to represent this condition, the printable representation of keepOnGoing would go into an infinite loop trying to print its fourth element:

#(1, 2, 3, #(1, 2, 3, #(1, 2, 3, ...

Instead, keepOnGoing prints using a special format that looks like this:

print keepOnGoing 
#1=#(1, 2, 3, #1#)

In this format, the object that contains a reference to itself is specified by a number (#1 in this case), an equal sign, and the printable representation of itself. Then, in the list of elements, any elements that refer to that same object are indicated by that number, surrounded by hash signs (#1# in this case).

Collections that contain multiple copies of the same object are printed using a recursive format:

x := "elbow"
b := #(x, x)
print b
#(#1="elbow", #1#)

In this example, the #1="elbow" part refers to the first occurrence of x, and #1# refers to all other occurrences.

In objects that contain multiple recursive or repeated objects, those collections are numbered consecutively:

a := "elbow"
b := "knee"
c := #(a, b, b, a)
print c
#(#2="elbow", #1="knee", #1#, #2#)


This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.

Copyright 1996 Apple Computer, Inc. All Rights Reserved.